// matrix_operations.c
#include "matrix_operations.h"
#include <string.h>

// 创建矩阵并分配内存
Matrix create_matrix(uint32_t rows, uint32_t cols) {
    Matrix mat;
    mat.rows = rows;
    mat.cols = cols;
    mat.data = (uint8_t*)malloc(rows * cols * sizeof(uint8_t));
    if (mat.data == NULL) {
        fprintf(stderr, "Error: Memory allocation failed in create_matrix\n");
        mat.rows = 0;
        mat.cols = 0;
    }
    return mat;
}

// 释放矩阵内存
void free_matrix(Matrix mat) {
    if (mat.data != NULL) {
        free(mat.data);
    }
}

// 复制矩阵
Matrix copy_matrix(Matrix mat) {
    Matrix new_mat = create_matrix(mat.rows, mat.cols);
    if (new_mat.data != NULL) {
        memcpy(new_mat.data, mat.data, mat.rows * mat.cols * sizeof(uint8_t));
    }
    return new_mat;
}

Matrix read_matrix(const char *filename) {
    Matrix mat;
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        fprintf(stderr, "Error opening matrix file: %s\n", filename);
        mat.rows = 0;
        mat.cols = 0;
        mat.data = NULL;
        return mat;
    }
    // 读取矩阵的行数和列数
    if (fscanf(file, "%u %u", &mat.rows, &mat.cols) != 2) {
        fprintf(stderr, "Error reading matrix dimensions from file: %s\n", filename);
        fclose(file);
        mat.rows = 0;
        mat.cols = 0;
        mat.data = NULL;
        return mat;
    }
    // 分配内存用于存储矩阵元素
    mat.data = (uint8_t *)malloc(mat.rows * mat.cols * sizeof(uint8_t));
    if (mat.data == NULL) {
        fprintf(stderr, "Memory allocation failed for matrix data\n");
        fclose(file);
        mat.rows = 0;
        mat.cols = 0;
        mat.data = NULL;
        return mat;
    }
    // 读取矩阵元素并存储到分配好的内存中
    for (uint32_t i = 0; i < mat.rows; i++) {
        for (uint32_t j = 0; j < mat.cols; j++) {
            uint32_t temp;
            if (fscanf(file, "%u", &temp) != 1) {
                fprintf(stderr, "Error reading matrix element at (%u, %u) from file: %s\n", i, j, filename);
                // 释放已分配的内存
                free(mat.data);
                fclose(file);
                mat.rows = 0;
                mat.cols = 0;
                mat.data = NULL;
                return mat;
            }
            mat.data[i * mat.cols + j] = (uint8_t)temp;
        }
    }
    fclose(file);
    return mat;
}

// 将矩阵展平为向量 (28x28 -> 784x1)
// 将矩阵展平为向量 (28x28 -> 784x1)
void matrix_to_vector(int rows, int cols, double matrix[rows][cols], double vector[1][rows * cols]) {
    int index = 0;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            vector[0][index++] = matrix[i][j];
        }
    }
}

// 从文本文件读取矩阵数据
Matrix read_txt_data(const char* filename) {
    FILE* file = fopen(filename, "r");
    if (!file) {
        fprintf(stderr, "Error opening file: %s\n", filename);
        return create_empty_matrix();
    }
    
    int rows, cols;
    if (fscanf(file, "%u %u", &rows, &cols) != 2) {
        fclose(file);
        return create_empty_matrix();
    }
    
    Matrix mat = create_matrix(rows, cols);
    for (uint32_t i = 0; i < rows; i++) {
        for (uint32_t j = 0; j < cols; j++) {
            uint32_t temp;
            if (fscanf(file, "%u", &temp) != 1) {
                fprintf(stderr, "Error reading matrix element at (%u,%u)\n", i, j);
                free_matrix(mat);
                fclose(file);
                return create_empty_matrix();
            }
            mat.data[i*cols+j]=(uint8_t)temp;
        }
    }
    
    fclose(file);
    return mat;
}

// 创建空矩阵 (用于错误处理)
Matrix create_empty_matrix() {
    Matrix mat;
    mat.rows = 0;
    mat.cols = 0;
    mat.data = NULL;
    return mat;
}

// 将一维向量转换为二维矩阵
void vector_to_matrix(int rows, int cols, double vector[1][rows * cols], double matrix[rows][cols]) {
    int index = 0;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = vector[0][index++];
        }
    }
}